home *** CD-ROM | disk | FTP | other *** search
/ Network Support Library / RoseWare - Network Support Library.iso / btrieve / tpbtrv.arc / BTRIEVE.ASM next >
Assembly Source File  |  1988-04-22  |  12KB  |  247 lines

  1. ;-----------------------------------------------------------------------------
  2. ;
  3. ;       This routine interfaces between Turbo Pascal programs and Btrieve
  4. ;       assembly routines.  This is a modified version for use with
  5. ;       Mulkey.PAS which passes the key buffer length to Btrieve.  To use
  6. ;       without this feature, remove references to KeyLen in the stack
  7. ;       structure below, force 255 in each call to Btrieve and rewrite the
  8. ;       parameter list to Btrv.
  9. ;
  10. ;       Copyright 1988 by Mark R. Boler  -  All Rights Reserved
  11. ;
  12. ;-----------------------------------------------------------------------------
  13. ;
  14. ;       This module is optimized primarily for the 80386 processor,
  15. ;       secondary to that, the 80286 processor.  The 8088/8086 processors
  16. ;       would benefit from a different algorithm for loading the parameters
  17. ;       to the Btrieve data buffer.  The format used here is:
  18. ;
  19. ;        push  [bp + xx]
  20. ;
  21. ;       This executes in about 5 clocks on the 80286 and 80386 processors
  22. ;       and about 25 clocks on the 8086 and about 33 clocks on the 8088 with
  23. ;       the added benefit of not having to explicitly subtract sp plus the
  24. ;       fact that the push opcodes take less code space.
  25. ;
  26. ;       The 8088/8086 processors should use:
  27. ;
  28. ;        mov   ax, [bp + xx]
  29. ;        mov   [bp - xx], ax
  30. ;
  31. ;       This executes in about 20 clocks on the 8086 and 28 clocks on the
  32. ;       8088 because when loading to/from the ax register, no EA calculation
  33. ;       is needed.  The reason this was not used on the 80286/80386 is because
  34. ;       on these procesors, this takes about 8 and 6 clocks respectively and
  35. ;       I liked the 5 and 5 clocks of the push mem16 method better. This may
  36. ;       make it harder to read but the Btrieve interface is called quite
  37. ;       repetitively in database applications and this was a good place to
  38. ;       do some major optimizing.
  39. ;
  40. ;-----------------------------------------------------------------------------
  41.  
  42. TITLE     BTRIEVE                       ; modified for Mulkey
  43.  
  44. DATA      SEGMENT  WORD PUBLIC
  45.  
  46.           ASSUME   DS:DATA
  47.  
  48.           ProcID   DW   ?               ; process Id for BMulti
  49.           Version  DW   ?               ; single/multi ProcID/No ProcID
  50.  
  51. DATA      ENDS
  52.  
  53. CODE      SEGMENT  WORD PUBLIC
  54.  
  55.           ASSUME   CS:CODE
  56.  
  57.           PUBLIC   Btrv, InitBtrv
  58.  
  59. ; FUNCTION Btrv(Op: WORD;                 MODIFIED FOR KEY LENGTH PASSING
  60. ;               VAR PosBlock;
  61. ;               VAR Data;
  62. ;               VAR DataLen: WORD;
  63. ;               VAR KBuf;
  64. ;               Key: BYTE;
  65. ;               KeyLen: BYTE): WORD; EXTERNAL;
  66.  
  67. StackRec  STRUC                         ; stack structure
  68. ;
  69. ;         These are the local variables passed to Btrieve as a data block
  70. ;         ---------------------------------------------------------------------
  71.           DBuf        DD   ?            ; address of data buffer
  72.           BufLen      DW   ?            ; data buffer length
  73.           PosInfo     DD   ?            ; address of positioning info
  74.           FCB         DD   ?            ; address of FCB
  75.           OpCode      DW   ?            ; operation code
  76.           KBuf        DD   ?            ; address of key buffer
  77.           KeyLength   DB   ?            ; length of key buffer
  78.           KeyNumber   DB   ?            ; key number
  79.           StatusAddr  DD   ?            ; address of status word
  80.           XFaceID     DW   ?            ; interface id 'va' for variable
  81. ;
  82. ;         This is the Status word that Btrieve uses to return the status info
  83. ;         ---------------------------------------------------------------------
  84.           Status      DW   ?            ; Status word
  85. ;
  86. ;         This is the return address
  87. ;         ---------------------------------------------------------------------
  88.           RetAddr     DD   ?            ; procedure far return address
  89. ;
  90. ;         These are the parameters passed to this function
  91. ;         ---------------------------------------------------------------------
  92.           KeyLen      DB   ?            ; key buffer length (byte)
  93.           KeyLenFill  DB   ?            ; byte filler
  94.           KeyNum      DB   ?            ; key number (byte)
  95.           KeyNumFill  DB   ?            ; byte filler
  96.           KeyBufOfs   DW   ?            ; offset address of key buffer
  97.           KeyBufSeg   DW   ?            ; segment address of key buffer
  98.           DataLen     DD   ?            ; address of data length word
  99.           DataBufOfs  DW   ?            ; offset address of data buffer
  100.           DataBufSeg  DW   ?            ; segment address of data buffer
  101.           PosBlock    DD   ?            ; address of position block
  102.           Function    DW   ?            ; Btrieve function number
  103. StackRec  ENDS
  104.  
  105. StackF    EQU    [bp - RetAddr]         ; reference to stack frame [bp]
  106. MinDosVer EQU    3                      ; minimum DOS version for multi-user
  107. PosOfs    EQU    38                     ; positioning info offset in PosBlock
  108. VarID     EQU    6176H                  ; variable data buffer ID ('va')
  109. BtrErr    EQU    20                     ; Return value when Btrieve not loaded
  110. MultiF    EQU    0ABH                   ; Code for multi function Btrieve
  111. BtrOffset EQU    033H                   ; offset of vector if Btrieve loaded
  112. VersionL  EQU    BYTE PTR es:Version    ; low byte of Version with es segment
  113. BtrInt    EQU    07BH                   ; Interrupt vectors
  114. Btr2Int   EQU    02FH                   ;     "        "
  115. ZInt      EQU    07FH                   ;     "        "
  116.  
  117. Btrv      PROC   FAR                    ; the Btrv function
  118.           mov    si, bp                 ; save bp in si
  119.           mov    bp, sp                 ; set up stack frame
  120.           mov    cx, Version            ; get version into cx
  121.           or     cl, cl                 ; see if Btrieve was found during init
  122.           jz     SHORT NotLoaded        ; jump if not loaded
  123.  
  124. ; allocate space for the Status word
  125.  
  126.           sub    sp, SIZE Status        ; allocate the stack space
  127.           mov    bx, sp                 ; save the offset in bx
  128.  
  129. ; store the interface ID
  130.  
  131.           mov    ax, VarID              ; get variable records interface ID
  132.           push   ax                     ; store it
  133.  
  134. ; store the address of the status word
  135.  
  136.           push   ss                     ; store the segment
  137.           push   bx                     ; and the offset
  138.  
  139. ; store the key number and key buffer size
  140.  
  141.           mov    al, StackF.KeyLen      ; get length of key buffer
  142.           mov    ah, StackF.KeyNum      ; get key number
  143.           push   ax                     ; and store them
  144.  
  145. ; store the address of the key buffer
  146.  
  147.           push   StackF.KeyBufSeg       ; store segment of key buffer
  148.           push   StackF.KeyBufOfs       ; store offset of key buffer
  149.  
  150. ; store the Btrieve operation code
  151.  
  152.           push   StackF.Function        ; store the op code
  153.  
  154. ; calculate and store positioning and FCB addresses
  155.  
  156.           les    ax, StackF.PosBlock    ; es:ax => pos block
  157.           push   es                     ; store FCB segment
  158.           push   ax                     ; store FCB offset
  159.           push   es                     ; store positioning info segment
  160.           add    ax, PosOfs             ; adjust positioning info offset
  161.           push   ax                     ; store positioning info offset
  162.  
  163. ; store data buffer length
  164.  
  165.           les    bx, StackF.DataLen     ; es:[bx] = data buffer length word
  166.           push   es:[bx]                ; store the length
  167.  
  168. ; store data buffer address
  169.  
  170.           push   StackF.DataBufSeg      ; store data buffer segment
  171.           push   StackF.DataBufOfs      ; store data buffer offset
  172.  
  173. ; set up call to Btrieve, make ds:[dx] = data block for Btrieve
  174.  
  175.           mov    di, ds                 ; save ds in di for now
  176.           mov    dx, sp                 ; stack pointer is data block offset
  177.           mov    ax, ss                 ; make ds = stack segment
  178.           mov    ds, ax
  179.  
  180. ; see which version to call and do it
  181.  
  182.           or     ch, ch                 ; see if it is single or multi-user
  183.           je     SHORT NotMulti         ; then jump around multi code if single
  184.  
  185. ; make the call to multi-user btrieve
  186.  
  187. MakeCall:
  188.           mov    es, di                 ; copy our saved ds into es for now
  189.           mov    ax, cx                 ; set up ax with Version word from cx
  190.           mov    bx, es:ProcID          ; set Process ID for BMulti
  191.           int    Btr2Int                ; call it
  192.           or     al, al                 ; see if it is zero
  193.           jz     SHORT DoneCall         ; if so then jump ahead
  194.           mov    ax, 0200H
  195.           int    ZInt                   ; make the interrupt
  196.           jmp    SHORT MakeCall         ; then loop
  197. DoneCall:
  198.           test   cl, 00000010B          ; should we set the process ID
  199.           jnz    SHORT SetDBuf          ; if not then jump
  200.           mov    es:ProcID, bx          ; otherwise store the new process ID
  201.           inc    cx                     ; we have process ID
  202.           mov    VersionL, cl           ; set version for next time around
  203.           jmp    SHORT SetDBuf          ; then jump around single-user code
  204. NotLoaded:
  205.           mov    ax, BtrErr             ; set error code
  206.           jmp    SHORT Done             ; and return
  207. NotMulti:
  208.           int    BtrInt                 ; process request for single-user
  209. SetDBuf:
  210.           mov    ds, di                 ; get our data segment back from di
  211.           mov    bx, sp                 ; ss:[bx] = data block
  212.           mov    ax, ss:[bx].BufLen     ; load data buffer length into ax
  213.           les    bx, StackF.DataLen     ; es:[bx] = data length word
  214.           mov    es:[bx], ax            ; store the data buffer length
  215.           mov    ax, StackF.Status      ; set function return code
  216. Done:
  217.           mov    sp, bp                 ; de-allocate local data (pushed)
  218.           mov    bp, si                 ; restore bp from si
  219.           ret    22                     ; clean up and return to caller
  220. Btrv      ENDP
  221.  
  222. InitBtrv  PROC   NEAR
  223.           mov    ax, 3500H + BtrInt     ; DOS get interrupt vector function
  224.           int    21H                    ; offset comes back in bx
  225.           xor    dx, dx                 ; clear out dx
  226.           cmp    bx, BtrOffset          ; is Btrieve resident
  227.           jne    SHORT IDone            ; jump if not and set Version
  228.           inc    dx                     ; make dx = 1
  229.           mov    ah, 30H                ; check the DOS version number
  230.           int    21H                    ; call DOS
  231.           cmp    al, MinDosVer          ; DOS major version number
  232.           jb     SHORT IDone            ; if < DOS 3.xx then set Version
  233.           mov    al, dh                 ; clear out al
  234.           mov    ah, MultiF             ; see if it is multi-user version
  235.           int    Btr2Int                ; see what Btrieve tells us it is
  236.           cmp    al, 'M'                ; is it a multi-user version
  237.           jne    SHORT IDone            ; jump if it is
  238.           mov    dh, ah                 ; set to multi-user
  239. IDone:
  240.           mov    ds:Version, dx         ; store dx into version
  241.           ret                           ; return to caller
  242. InitBtrv  ENDP
  243.  
  244. CODE      ENDS
  245.  
  246.           END
  247.